package com.faceidentify

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.*
import android.media.AudioManager
import android.media.FaceDetector
import android.media.MediaPlayer
import android.net.Uri
import android.os.Bundle
import android.os.Handler
import android.os.Message
import android.util.Base64
import android.util.Log
import android.util.Size
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.camera.core.CameraSelector
import androidx.camera.core.ImageCapture
import androidx.camera.core.ImageCapture.OutputFileOptions
import androidx.camera.core.ImageCapture.OutputFileResults
import androidx.camera.core.ImageCaptureException
import androidx.camera.core.Preview
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.camera.view.PreviewView
import androidx.core.content.ContextCompat
import com.google.common.util.concurrent.ListenableFuture
import com.google.gson.JsonObject
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.IOException
import java.util.concurrent.ExecutionException

class IdentifyRecognitionActivity:AppCompatActivity() {
    private var paint: Paint? = null
    private var previewView: PreviewView? = null
    private var cameraProviderFuture: ListenableFuture<ProcessCameraProvider>? = null
    private var cameraProvider: ProcessCameraProvider? = null
    private var imageCapture: ImageCapture? = null
    private var previewBitmap: Bitmap? = null
    private var previewBitmap64: String? = null
    private var icon: ImageView? = null
    private var httpHelper: HttpHelper? = null


    private var context: Context? = null

    //识别接口
    private var url = "https://aip.baidubce.com/rest/2.0/face/v3/search?access_token=24.75fe8070f1bf141733dfbb61b7d9357e.2592000.1626751148.282335-23997882"


    private var faceInfo: TextView? = null
    private var mediaPlayer: MediaPlayer? = null
    private var txtStatus: TextView? = null
    private var uri: Uri? = null

    @SuppressLint("HandlerLeak")
    private val handler: Handler = object : Handler() {
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            if (msg.what == 1) {
                takePhone()
            }
            if (msg.what == 2) {
                resetInfo()
                faceInfo!!.text = "正在回到主页面"
                startVoice()
                sendEmptyMessageDelayed(3,4000)
            }
            if (msg.what == 3){
                finish()
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_identify_recognition)
        context = this
        initView()
    }

    private fun initView() {
        httpHelper = HttpHelper.getInstance()
        //播报语音
        mediaPlayer = MediaPlayer()
        previewView = findViewById<View>(R.id.previewView) as PreviewView?
        icon = findViewById<View>(R.id.icon) as ImageView?
        faceInfo = findViewById<View>(R.id.faceInfo) as TextView?
        txtStatus = findViewById<View>(R.id.txtStatus) as TextView?

        //画脸工具
        paint = Paint()
        paint!!.color = Color.RED
        paint!!.strokeWidth = 6f
        paint!!.style = Paint.Style.STROKE
    }

    override fun onStart() {
        super.onStart()
        cameraProviderFuture = ProcessCameraProvider.getInstance(applicationContext)
        cameraProviderFuture!!.addListener({
            try {
                cameraProvider = cameraProviderFuture!!.get()
                bindImageCapture(cameraProvider!!)
            } catch (e: ExecutionException) {
                e.printStackTrace()
            } catch (e: InterruptedException) {
                e.printStackTrace()
            }
        }, ContextCompat.getMainExecutor(applicationContext))
        faceInfo!!.text = "请正视摄像头"
        startVoice()
        handler.sendEmptyMessageDelayed(1, 3000)
    }


    //相机和预览功能绑定
    private fun bindImageCapture(cameraProvider: ProcessCameraProvider) {
        //CameraX 相机绑定
        imageCapture = ImageCapture.Builder() //优化捕获速度，可能降低图片质量
                .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY) //设置宽高比
                .setTargetResolution(Size(1280, 720)) //设置初始的旋转角度
                .build()
        val preview = Preview.Builder().build()
        val cameraSelector = CameraSelector.Builder()
                .requireLensFacing(CameraSelector.LENS_FACING_FRONT).build()
        preview.setSurfaceProvider(previewView!!.createSurfaceProvider())
        cameraProvider.bindToLifecycle(this, cameraSelector,
                imageCapture, preview)
    }


    //拍照功能
    private fun takePhone() {
        val file = File("/sdcard/Success-Import", "许硕.png")
        if (file.exists()) {
            file.delete()
        }
        val outputFileOptions = OutputFileOptions.Builder(file)
                .build()
        imageCapture!!.takePicture(outputFileOptions, ContextCompat.getMainExecutor(applicationContext), object : ImageCapture.OnImageSavedCallback {
            override fun onImageSaved(outputFileResults: OutputFileResults) {
                var savedUri = outputFileResults.savedUri
                if (savedUri == null) {
                    savedUri = Uri.fromFile(file)
                    Log.e("信息", savedUri.path + "")
                    var bitmap = BitmapFactory.decodeFile(savedUri.path)
                    var m = Matrix()
                    m.postScale(-1f, 1f)
                    previewBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, m, true)
                    previewBitmap64 = bitmapToBase64(previewBitmap)
                    drawFaceRect(previewBitmap)
                    if (icon!!.drawable != null) {
                        checkFace(previewBitmap)
                    }
                }
            }

            override fun onError(exception: ImageCaptureException) {
                Log.e("失败", exception.message!!)
            }
        })
    }

    //在线请求
    private fun checkFace(bitmap: Bitmap?) {
        runOnUiThread { //人脸识别方法
            FaceRecognition()
        }
    }
    private fun FaceRecognition() {
        resetInfo()
        val jsonObject = JsonObject()
        jsonObject.addProperty("image", previewBitmap64)
        jsonObject.addProperty("liveness_control", "NORMAL")
        jsonObject.addProperty("group_id_list", "2021_6_20_group1")
        jsonObject.addProperty("image_type", "BASE64")
        jsonObject.addProperty("quality_control", "LOW")

        httpHelper!!.postJsonObject(url, jsonObject, object : ResponseListener {
            override fun doAction(jsonObject: JsonObject?) {
                Log.e("json", jsonObject.toString())
                resultJudgment(jsonObject)
                startVoice()
            }
        })
    }

    private fun resetInfo() {
        txtStatus?.setText(null)
        faceInfo?.setText(null)
    }


    //请求结果码判断
    private fun resultJudgment(jsonObject: JsonObject?) {
        var error_code = jsonObject!!["error_code"].asInt
        if (error_code == 0) {
            val result = jsonObject["result"].asJsonObject
            val user_list = result["user_list"].asJsonArray[0].asJsonObject
            val user_info = user_list["user_info"].asString
            val score = user_list["score"].asString
            val douScore = score.toDouble()

            if (douScore >= 80) {
                txtStatus!!.text = "欢迎光临,${user_info}"
                faceInfo!!.text = "验证通过"

                handler.sendEmptyMessageDelayed(2, 4000)
            } else if (douScore < 80 && douScore >= 30) {
                faceInfo!!.text = "特征提取失败"
                handler.sendEmptyMessageDelayed(1, 3000)
            } else if (douScore < 30) {
                faceInfo!!.text = "验证失败,非本人"
                handler.sendEmptyMessageDelayed(2, 4000)
            }
        } else if (error_code == 222202) {
            faceInfo!!.text = "图片中无此人脸"
            handler.sendEmptyMessageDelayed(1, 3000)
        } else if (error_code == 222203) {
            faceInfo!!.text = "无法解析人脸"
            handler.sendEmptyMessageDelayed(1, 3000)
        } else if (error_code == 222207) {
            faceInfo!!.text = "验证失败,非本人"
            handler.sendEmptyMessageDelayed(2, 4000)
        } else if (error_code == 223106) {
            faceInfo!!.text = "该人脸不存在"
            handler.sendEmptyMessageDelayed(1, 3000)
        } else if (error_code == 223100) {
            faceInfo!!.text = "用户组不存在"
            handler.sendEmptyMessageDelayed(2, 3000)
        } else if (error_code == 223113) {
            faceInfo!!.text = "请勿遮挡面部"
            handler.sendEmptyMessageDelayed(1, 3000)
        } else if (error_code == 223114) {
            faceInfo!!.text = "人脸模糊"
            handler.sendEmptyMessageDelayed(1, 3000)
        } else if (error_code == 223115) {
            faceInfo!!.text = "人人脸光照不好"
            handler.sendEmptyMessageDelayed(1, 3000)
        } else if (error_code == 223116) {
            faceInfo!!.text = "人脸不完整"
            handler.sendEmptyMessageDelayed(1, 3000)
        } else if (error_code == 223120) {
            faceInfo!!.text = "活体检测未通过"
            handler.sendEmptyMessageDelayed(1, 3000)
        } else if (error_code == 223121) {
            faceInfo!!.text = "请勿遮挡左眼"
            handler.sendEmptyMessageDelayed(1, 3000)
        } else if (error_code == 223122) {
            faceInfo!!.text = "请勿遮挡右眼"
            handler.sendEmptyMessageDelayed(1, 3000)
        } else if (error_code == 223123) {
            faceInfo!!.text = "请勿遮挡左脸颊"
            handler.sendEmptyMessageDelayed(1, 3000)
        } else if (error_code == 223124) {
            faceInfo!!.text = "请勿遮挡右脸颊"
            handler.sendEmptyMessageDelayed(1, 3000)
        } else if (error_code == 223125) {
            faceInfo!!.text = "请勿遮挡下巴"
            handler.sendEmptyMessageDelayed(1, 3000)
        } else if (error_code == 223126) {
            faceInfo!!.text = "请勿遮挡鼻子"
            handler.sendEmptyMessageDelayed(1, 3000)
        } else if (error_code == 223127) {
            faceInfo!!.text = "请勿遮挡嘴巴"
            handler.sendEmptyMessageDelayed(1, 3000)
        } else if (error_code == 223129) {
            faceInfo!!.text = "请面向正前方"
            handler.sendEmptyMessageDelayed(1, 3000)
        }
    }

    private fun startVoice() {
        mediaPlayer!!.reset()
        uri = Uri.parse("https://tsn.baidu.com/text2audio?tex=" + faceInfo!!.text.toString().trim { it <= ' ' } + txtStatus!!.text.toString().trim { it <= ' ' } + "&lan=zh&cuid=10.0.19042.1052&ctp=1&tok=24.902233477ec4f5c7a7ae535c3c763813.2592000.1626685339.282335-24368715&audio=3")
        try {
            mediaPlayer!!.setDataSource(applicationContext, uri!!)
            mediaPlayer!!.setAudioStreamType(AudioManager.STREAM_MUSIC)
            mediaPlayer!!.prepareAsync()
            mediaPlayer!!.setOnPreparedListener { mediaPlayer!!.start() }
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }

    fun bitmapToBase64(bitmap: Bitmap?): String? {
        var result: String? = null
        var baos: ByteArrayOutputStream? = null
        try {
            if (bitmap != null) {
                baos = ByteArrayOutputStream()
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos)
                baos.flush()
                baos.close()
                val bitmapBytes = baos.toByteArray()
                result = Base64.encodeToString(bitmapBytes, Base64.DEFAULT)
            }
        } catch (e: IOException) {
            e.printStackTrace()
        } finally {
            try {
                if (baos != null) {
                    baos.flush()
                    baos.close()
                }
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
        return result
    }

    fun drawFaceRect(bitmap1: Bitmap?) {
        var copybitmap = bitmap1?.copy(Bitmap.Config.RGB_565, true)
        icon!!.setImageBitmap(copybitmap)
        val faceDetector = FaceDetector(copybitmap!!.width, copybitmap!!.height, 10)
        val faces = arrayOfNulls<FaceDetector.Face>(10)
        val realFaceNum = faceDetector.findFaces(copybitmap, faces)
        if (realFaceNum > 0) {
            faces?.let { drawFacesArea(it, copybitmap) } ?: Log.e("未检测到人脸", "")
        }
    }

    private fun drawFacesArea(faces: Array<FaceDetector.Face?>, copybitmap: Bitmap?) {
        var eyesDistance = 0f //两眼间距
        val canvas = Canvas(copybitmap!!)
        for (i in faces.indices) {
            val face: FaceDetector.Face? = faces.get(i)
            if (face != null) {
                val pointF = PointF()
                face.getMidPoint(pointF) //获取人脸中心点
                eyesDistance = face.eyesDistance() + 20 //获取人脸两眼的间距
                //画出人脸的区域
                canvas.drawRect(pointF.x - eyesDistance, pointF.y - eyesDistance - 10, pointF.x + eyesDistance, pointF.y + eyesDistance + 60, paint!!)
            }
        }
        //画出人脸区域后要刷新ImageView
        //画出人脸区域后要刷新ImageView
        icon!!.invalidate()
    }


    override fun onDestroy() {
        super.onDestroy()
        finish()
    }


}